package com.example.demo.service.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.mapper.*;
import com.example.demo.pojo.Accounts.FundAccounts;
import com.example.demo.pojo.Accounts.TotalAmount;
import com.example.demo.pojo.Accounts.UserFundAccounts;
import com.example.demo.pojo.Competitions.*;
import com.example.demo.pojo.R;
import com.example.demo.service.CompetitionService;
import com.example.demo.utils.TokenUtil.decryptToken;
import com.example.demo.utils.TokenUtil.spiltUtils;
import com.example.demo.utils.UserUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.example.demo.utils.ConstantUtils.FINISH;

@Service
@Slf4j
public class CompetitionServiceImpl extends ServiceImpl<CompetitionMapper, Competitions> implements CompetitionService {

    @Resource
    private CompetitionMapper competitionMapper;
    @Resource
    private UserCompetitionMapper userCompetitionMapper;
    @Resource
    private FundAccountMapper fundAccountMapper;

    @Resource
    private UserFundAccountMapper userFundAccountMapper;
    @Resource
    private InvitedUserIdsMapper invitedUserIdsMapper;

    @Resource
    private TotalAmountMapper totalAmountMapper;
    @Resource
    private UserUtil userUtil;
    @Autowired
    private CompetitionPasscodeMapper competitionPasscodeMapper;

    @Override
    public R<T> joinCompetition(String token, Integer id, String passcode) {
        //获取当前用户的id
        String decrypt = decryptToken.decrypt(token);
        String userName = spiltUtils.getUserName(decrypt);
        Integer userId = userUtil.getUserId(userName);
        //判断是否实名
        boolean realNameAuthentication = userUtil.getRealNameAuthentication(userId);
        if (!realNameAuthentication) {
            return R.failed("你还未进行实名认证！");
        }
        //判断比赛口令是否有效
        QueryWrapper<CompetitionPasscode> competitionPasscodeQueryWrapper = new QueryWrapper<>();
        competitionPasscodeQueryWrapper.eq("competition_id", id).eq("passcode", passcode);
        CompetitionPasscode competitionPasscode = competitionPasscodeMapper.selectOne(competitionPasscodeQueryWrapper);
        if (competitionPasscode == null) {
            return R.failed("比赛口令有误，请重新输入！");
        }
        QueryWrapper<Competitions> competitionsQueryWrapper = new QueryWrapper<>();
        competitionsQueryWrapper.eq("competition_id", id);
        Competitions competitions = competitionMapper.selectOne(competitionsQueryWrapper);
        // 检查是否获取到比赛信息
        if (competitions == null) {
            return R.failed("比赛不存在！");
        }
        // 获取比赛的截止日期
        Date deadline = competitions.getEndDate();

        // 获取当前日期
        Date now = new Date();

        // 判断比赛截止日期是否到期
        if (now.after(deadline)) {
            return R.failed("比赛已截止，无法参加！");
        }
        //判断是否退过赛
        QueryWrapper<UserCompetitions> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("competition_id", id)
                .eq("real_name", userUtil.getRealNameById(userId))
                .eq("status", "退赛");
        UserCompetitions userCompetitionPojo = userCompetitionMapper.selectOne(queryWrapper);
        if (userCompetitionPojo != null) {
            userCompetitionPojo.setStatus("参赛");
            int update = userCompetitionMapper.updateById(userCompetitionPojo);
            if (update > 0) {
                //生成平台比赛账户
                FundAccounts fundAccount = new FundAccounts();
                fundAccount.setAccountId(id);
                fundAccount.setUserId(userId);
                fundAccount.setBankAccount("股票账户");
                fundAccount.setTotalAsset(BigDecimal.ZERO);
                fundAccount.setAvailableFund(BigDecimal.ZERO);
                fundAccount.setFrozenFund(BigDecimal.ZERO);
                fundAccount.setPositionProfitLoss(BigDecimal.ZERO);
                fundAccount.setPositionValue(BigDecimal.ZERO);
                int fundAccountInsert = fundAccountMapper.insert(fundAccount);
                //创建银行账户
                UserFundAccounts userFundAccount = new UserFundAccounts();
                userFundAccount.setUserAccountId(id);
                userFundAccount.setUserId(userId);
                userFundAccount.setUserBankAccount("银行账户");
                userFundAccount.setUserTotalAsset(BigDecimal.ZERO);
                userFundAccount.setAvailableFund(BigDecimal.ZERO);
                int userFundAccountInsert = userFundAccountMapper.insert(userFundAccount);
                //生成InvitedUserIds
                InvitedUserIds invitedUserIds = new InvitedUserIds();
                invitedUserIds.setCompetitionId(id);
                invitedUserIds.setUserId(userId);
                int invitedUserIdsInsert = invitedUserIdsMapper.insert(invitedUserIds);
                //新建总金额表
                TotalAmount totalAmount = new TotalAmount();
                totalAmount.setCompetitionId(id);
                totalAmount.setUserId(userId);
                totalAmount.setAmount(BigDecimal.ZERO);
                int totalAmountInsert = totalAmountMapper.insert(totalAmount);
                if (fundAccountInsert > 0 && userFundAccountInsert > 0 && invitedUserIdsInsert > 0 && totalAmountInsert > 0) {
                    return R.success("报名成功！");
                }
                return R.failed("账户创建失败！请退出比赛后重新报名！");
            }
        }
        UserCompetitions userCompetition = new UserCompetitions();
        userCompetition.setRealName(userUtil.getRealNameById(userId));
        userCompetition.setUserId(userId);
        userCompetition.setCompetitionId(id);
        userCompetition.setStatus("参赛");
        int insert = userCompetitionMapper.insert(userCompetition);
        if (insert > 0) {
            //生成平台比赛账户
            FundAccounts fundAccount = new FundAccounts();
            fundAccount.setAccountId(id);
            fundAccount.setUserId(userId);
            fundAccount.setBankAccount("股票账户");
            fundAccount.setTotalAsset(BigDecimal.ZERO);
            fundAccount.setAvailableFund(BigDecimal.ZERO);
            fundAccount.setFrozenFund(BigDecimal.ZERO);
            fundAccount.setPositionProfitLoss(BigDecimal.ZERO);
            fundAccount.setPositionValue(BigDecimal.ZERO);
            int fundAccountInsert = fundAccountMapper.insert(fundAccount);
            //创建银行账户
            UserFundAccounts userFundAccount = new UserFundAccounts();
            userFundAccount.setUserAccountId(id);
            userFundAccount.setUserId(userId);
            userFundAccount.setUserBankAccount("银行账户");
            userFundAccount.setUserTotalAsset(BigDecimal.ZERO);
            userFundAccount.setAvailableFund(BigDecimal.ZERO);
            int userFundAccountInsert = userFundAccountMapper.insert(userFundAccount);
            //生成InvitedUserIds
            InvitedUserIds invitedUserIds = new InvitedUserIds();
            invitedUserIds.setCompetitionId(id);
            invitedUserIds.setUserId(userId);
            int invitedUserIdsInsert = invitedUserIdsMapper.insert(invitedUserIds);
            if (fundAccountInsert > 0 && userFundAccountInsert > 0 && invitedUserIdsInsert > 0) {
                return R.success("报名成功！");
            }
            return R.failed("账户创建失败！请退出比赛后重新报名！");
        }
        return R.failed("报名失败！");
    }

    @Override
    public R<Map<String, Object>> getAllCompetition(int pageNum, int pageSize) {
        Page<Competitions> page = new Page<>(pageNum, pageSize, true);
        QueryWrapper<Competitions> QueryWrapper = new QueryWrapper<>();
        IPage<Competitions> competitionsIPage = competitionMapper.selectPage(page, QueryWrapper);
        List<Competitions> competitions = competitionsIPage.getRecords();
        long totalCount = competitionsIPage.getTotal();
        // 使用 Log 记录日志
        log.info("总共找到记录数：{}", totalCount);
        log.info("当前页码：{}", page.getCurrent());
        log.info("总页数：{}", page.getPages());

        Map<String, Object> result = new HashMap<>();
        result.put("competitions", competitions);
        result.put("totalCount", totalCount);

        return R.success(result);
    }

    @Override
    public R<Map<String, Object>> getJoinCompetitionUserById(int id, int pageNum, int pageSize) {
        // 初始化分页对象
        Page<UserCompetitions> page = new Page<>(pageNum, pageSize);
        // 构建查询条件
        QueryWrapper<UserCompetitions> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("competition_id", id);
        // 执行查询
        IPage<UserCompetitions> iPage = userCompetitionMapper.selectPage(page, queryWrapper);

        // 直接从iPage获取记录和总数
        List<UserCompetitions> userCompetitions = iPage.getRecords();
        long totalCount = iPage.getTotal();

        // 记录日志
        log.info("总共找到参赛用户记录数：{}", totalCount);
        log.info("当前页码：{}", iPage.getCurrent());
        log.info("总页数：{}", iPage.getPages());

        // 构建结果映射
        Map<String, Object> result = new HashMap<>();
        result.put("totalCount", totalCount);
        result.put("userCompetitions", userCompetitions);

        // 返回成功响应
        return R.success(result);
    }

    @Override
    public R<Competitions> getCompetitionById(Integer CompetitionsId) {
        //否则到数据库中查询
        QueryWrapper<Competitions> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("competition_id", CompetitionsId);
        Competitions competitions = competitionMapper.selectOne(queryWrapper);
        return R.success(competitions);
    }

    @Override
    public void proveCompetition(Integer id) {
        //查询比赛截止时间
        QueryWrapper<Competitions> competitionsQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Competitions> queryWrapper = competitionsQueryWrapper.eq("id", id);
        Date endDate = competitionMapper.selectOne(queryWrapper).getEndDate();
        //判断是否大于当前时间
        // 获取当前时间
        Date currentDate = new Date();

        // 判断比赛截止时间是否大于当前时间
        if (endDate.after(currentDate)) {
            log.info("--------------比赛尚未结束");
        } else {
            // 如果比赛截止时间在当前时间之前或恰好等于当前时间，表示比赛已经结束
            log.info("------------比赛已经结束");
            //修改数据库里的比赛状态
            UpdateWrapper<Competitions> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", id).set("status", FINISH);
            competitionMapper.update(null, updateWrapper);
            log.info("-------------比赛状态修改成功");
        }
    }

    @Override
    public R<Competitions> getCompetitionsById(int id) {
        QueryWrapper<Competitions> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("competition_id", id);
        Competitions competitions = competitionMapper.selectOne(queryWrapper);
        if (competitions != null) {
            return R.success(competitions);
        }
        return null;
    }

    @Override
    public R<List<UserCompetitionDetail>> getUserCompetitions(String token) {
        //获取当前用户的id
        String decrypt = decryptToken.decrypt(token);
        String userName = spiltUtils.getUserName(decrypt);
        Integer userId = userUtil.getUserId(userName);
        //查询用户已参加的比赛详情
        List<UserCompetitionDetail> competitionsByUserId = competitionMapper.getCompetitionsByUserId(userId);
        return R.success(competitionsByUserId);
    }

    @Override
    public R<List<Competitions>> getCompetitionsByCompetitionsName(String competitionsName) {
        QueryWrapper<Competitions> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("name", competitionsName);
        List<Competitions> competitions = competitionMapper.selectList(queryWrapper);
        if (competitions != null) {
            return R.success(competitions);
        } else {
            return R.failed("没有搜索到相关比赛！");
        }
    }



}
